package com.csun.cmny.provider.service.impl;

import com.csun.cmny.base.enums.ErrorCodeEnum;
import com.csun.cmny.core.support.BaseService;
import com.csun.cmny.provider.dao.DmcWatchDataMapper;
import com.csun.cmny.provider.dao.DmcWatchDataSleepMapper;
import com.csun.cmny.provider.exceptions.DmcBizException;
import com.csun.cmny.provider.model.domain.*;
import com.csun.cmny.provider.model.dto.watch.WatchHeartQueryDto;
import com.csun.cmny.provider.model.dto.watch.WatchStepQueryDto;
import com.csun.cmny.provider.model.vo.WatchOldmanAddressVo;
import com.csun.cmny.provider.model.vo.watch.*;
import com.csun.cmny.provider.resolver.CmnyMessageSource;
import com.csun.cmny.provider.service.*;
import com.csun.cmny.util.PubUtils;
import com.csun.cmny.util.PublicUtil;
import com.google.common.base.Preconditions;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Auther: chisj chisj@foxmal.com
 * @Date: 2019-01-17 16:19
 * @Description: the class dmc watch data service impl
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class DmcWatchDataServiceImpl extends BaseService<DmcWatchData> implements DmcWatchDataService {

    @Resource
    private CmnyMessageSource cmnyMessageSource;
    @Resource
    private DmcDeviceService dmcDeviceService;
    @Resource
    private DmcWatchDataMapper dmcWatchDataMapper;
    @Resource
    private DmcWatchDataHeartService dmcWatchDataHeartService;
    @Resource
    private DmcWatchDataSleepService dmcWatchDataSleepService;
    @Resource
    private DmcWatchDataStepService dmcWatchDataStepService;
    @Resource
    private DmcWatchDataLocationService dmcWatchDataLocationService;
    @Resource
    private DmcWatchAlarmClockService dmcWatchAlarmClockService;

    /**
     * query real watch data by device id
     *
     * @param deviceId device id
     *
     * @return the dmc device service
     */
    @Override
    public DmcWatchData queryRealWatchDataByDeviceId(Long deviceId) {
        return null;
    }

    /**
     * init dmc watch data
     *
     * @param deviceId device id
     * @return the int.
     */
    @Override
    public Integer initDmcWatchData(Long deviceId) {

        DmcWatchData dmcWatchData = new DmcWatchData();
        dmcWatchData.setDeviceId(deviceId);

        Integer result = dmcWatchDataMapper.insertSelective(dmcWatchData);

        return result;
    }

    /**
     * remove dmc watch data
     *
     * @param deviceId device id
     * @return the int.
     */
    @Override
    public Integer removeDmcWatchData(Long deviceId) {

        Integer result = dmcWatchDataMapper.deleteByPrimaryKey(deviceId);

        // 删除手环心率数据
        dmcWatchDataHeartService.removeDmcWatchDataHeart(deviceId);

        // 删除手环位置数据
        dmcWatchDataLocationService.removeDmcWatchDataLocation(deviceId);

        // 删除手环睡眠数据
        dmcWatchDataSleepService.removeDmcWatchDataSleep(deviceId);

        // 删除手环步数数据
        dmcWatchDataStepService.removeDmcWatchDataStep(deviceId);

        return result;
    }

    /**
     * show watch data by device id
     *
     * @param deviceId device id
     * @return the dmc watch data vo
     */
    @Override
    public DmcWatchDataVo showDataByDeviceId(Long deviceId) {

        // 1.判断设备是否存在 && 设备是否为孝心手环
        DmcDevice dmcDevice = dmcDeviceService.checkDeviceIsWatchByDeviceId(deviceId);
        if (PublicUtil.isEmpty(dmcDevice)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610014, deviceId);
        }

        DmcWatchDataVo dmcWatchDataVo = dmcWatchDataMapper.showDataByDeviceId(deviceId);
        if (PublicUtil.isEmpty(dmcWatchDataVo)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610044, deviceId);
        }

        if (PublicUtil.isEmpty(dmcWatchDataVo.getOldmanId())) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610044, deviceId);
        }
        dmcWatchDataVo.setBind(true);

        /**
         * @date    2020-04-09
         * @author  chisj
         * @desc    修复bug #4685 返回最近提醒倒计时
         */
        Map<String,Object> clockMap = dmcWatchAlarmClockService.selectByDeviceId(deviceId);
        if (PublicUtil.isEmpty(clockMap)) {
            dmcWatchDataVo.setClockTime("0");
        }else {
            dmcWatchDataVo.setClockTime(clockMap.get("minute") + "");
        }

        return dmcWatchDataVo;
    }

    /**
     * get current watch location by device id
     *
     * @param deviceId device id
     * @return the current watch location vo
     */
    @Override
    public WatchCurrentLocationVo getCurrentWatchLocationByDeviceId(Long deviceId) {

        // 1.判断设备是否存在 && 设备是否为孝心手环
        DmcDevice dmcDevice = dmcDeviceService.checkDeviceIsWatchByDeviceId(deviceId);
        if (PublicUtil.isEmpty(dmcDevice)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610014, deviceId);
        }

        // 2.获取手环数据
        DmcWatchDataVo dmcWatchDataVo = dmcWatchDataMapper.showDataByDeviceId(deviceId);
        if (PublicUtil.isEmpty(dmcWatchDataVo)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610044, deviceId);
        }

        // 3.判断设备是否绑定
        if (PublicUtil.isEmpty(dmcWatchDataVo.getOldmanId())) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610044, deviceId);
        }

        // 4.下发获取定位指令

        // 5.从缓存中获取手环数据
        WatchCurrentLocationVo watchCurrentLocationVo = new WatchCurrentLocationVo();
        BeanUtils.copyProperties(dmcWatchDataVo, watchCurrentLocationVo);

        return watchCurrentLocationVo;
    }

    /**
     * get watch data by device id
     *
     * @param deviceId device id
     * @return dmc watch data vo
     */
    @Override
    public DmcWatchDataVo getWatchDataByDeviceId(Long deviceId) {

        // 1.判断设备是否存在 && 设备是否为孝心手环
        DmcDevice dmcDevice = dmcDeviceService
                .checkDeviceIsWatchByDeviceId(deviceId);
        if (PublicUtil.isEmpty(dmcDevice)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610014, deviceId);
        }

        // 2.获取手环数据
        DmcWatchDataVo dmcWatchDataVo = dmcWatchDataMapper
                .showDataByDeviceId(deviceId);
        if (PublicUtil.isEmpty(dmcWatchDataVo)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610044, deviceId);
        }

        // 3.判断设备是否绑定
        if (PublicUtil.isEmpty(dmcWatchDataVo.getOldmanId())) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610044, deviceId);
        }

        return dmcWatchDataVo;
    }

    /**
     * query watch oldman address by oldman id list
     *
     * @param oldmanIds oldman id list
     * @return the list watch oldman address vo
     */
    @Override
    public List<WatchOldmanAddressVo> queryWatchOldmanAddressByOldmanIds(List<Integer> oldmanIds) {

        Preconditions.checkArgument(PublicUtil.isNotEmpty(oldmanIds),
                cmnyMessageSource.getMessage("oldman.id.list.null", null));

        List<WatchOldmanAddressVo> watchOldmanAddressVoList =
                dmcWatchDataMapper.queryWatchOldmanAddressByOldmanIds(oldmanIds);

        return watchOldmanAddressVoList;
    }

    @Override
    public Map<String, Object> getRecentData(Integer oldmanId) {
        return dmcWatchDataMapper.getRecentData(oldmanId);
    }
}
